package com.mxf.miaosha.controller;

import com.mxf.miaosha.VO.GoodsVO;
import com.mxf.miaosha.access.AccessLimit;
import com.mxf.miaosha.domain.MiaoshaOrder;
import com.mxf.miaosha.domain.MiaoshaUser;
import com.mxf.miaosha.domain.OrderInfo;
import com.mxf.miaosha.rabbitmq.MQSender;
import com.mxf.miaosha.rabbitmq.MiaoshaMessage;
import com.mxf.miaosha.redis.AccessKey;
import com.mxf.miaosha.redis.GoodsKey;
import com.mxf.miaosha.redis.MiaoshaKey;
import com.mxf.miaosha.redis.RedisService;
import com.mxf.miaosha.result.CodeMsg;
import com.mxf.miaosha.result.Result;
import com.mxf.miaosha.service.GoodsService;
import com.mxf.miaosha.service.MiaoshaService;
import com.mxf.miaosha.service.OrderService;
import com.mxf.miaosha.util.MD5Util;
import com.mxf.miaosha.util.UUIDUtil;
import com.rabbitmq.client.AMQP;
import com.sun.org.apache.bcel.internal.classfile.Code;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Controller
@RequestMapping("/miaosha/")
public class MiaoshaController implements InitializingBean {

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private MiaoshaService miaoshaService;

    @Autowired
    RedisService redisService;

    @Autowired
    MQSender sender;

    Map<Long, Boolean> localOverMap = new HashMap<Long, Boolean>();

    /**
     * 秒杀
     * @param model
     * @param user
     * @param goodsId
     * @return
     */
    @RequestMapping(value = "/{path}/do_miaosha", method = RequestMethod.POST)
    @ResponseBody
    public Result<Integer> do_miaosha(Model model, MiaoshaUser user,
                                      @RequestParam("goodsId") long goodsId, @PathVariable("path") String path) {
        model.addAttribute("user", user);
        if(user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }

        boolean check = miaoshaService.check(user, goodsId, path);
        if(!check) {
            return Result.error(CodeMsg.REQUEST_ILLEGAL);
        }

        // 内存标记减少redis访问
        boolean over = localOverMap.get(goodsId);
        if(over) {
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }

        // 预减库存
        long stock = redisService.decr(GoodsKey.getMiaoshaGoodsStock, "" + goodsId);
        if(stock < 0) {
            localOverMap.put(goodsId, true);
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }

        //判断是否已经秒杀到了
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
        if(order != null) {
            Result.error(CodeMsg.REPEAT_MIAOSHA);
        }

        // 入队
        MiaoshaMessage mm = new MiaoshaMessage();
        mm.setGoodsId(goodsId);
        mm.setUser(user);
        sender.sendMiaosha(mm);
        return Result.success(0); // 排队中

//        //判断库存
//        GoodsVO goods = goodsService.getGoodsVOByGoodsId(goodsId);
//        int stock = goods.getStockCount();
//        if(stock <= 0) {
//            model.addAttribute("errmsg", CodeMsg.MIAO_SHA_OVER.getMsg());
//            return "miaosha_fail";
//        }
//
//        //判断是否已经秒杀到了
//        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
//        if(order != null) {
//            model.addAttribute("errmsg", CodeMsg.REPEAT_MIAOSHA.getMsg());
//            return "miaosha_fail";
//        }
//
//        //减库存 下订单 写入秒杀订单
//        OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
//        model.addAttribute("orderInfo", orderInfo);
//        model.addAttribute("goods", goods);
//        return "order_detail";
    }

    @RequestMapping(value="/result", method=RequestMethod.GET)
    @ResponseBody
    public Result<Long> miaoshaResult(Model model,MiaoshaUser user,
                                      @RequestParam("goodsId")long goodsId) {
        model.addAttribute("user", user);
        if(user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        long result  =miaoshaService.getMiaoshaResult(user.getId(), goodsId);
        return Result.success(result);
    }

    @AccessLimit(seconds = 5, maxConut = 5, nendLogin = true)
    @RequestMapping(value = "/path", method = RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaPath(HttpServletRequest request, Model model, MiaoshaUser user, @RequestParam("goodsId") long goodsId,
                                         @RequestParam(value="verifyCode", defaultValue="0")int verifyCode) {
        model.addAttribute("user", user);
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }

//        // 接口限流
//        String url = request.getRequestURI(); // 获取请求的url
//        Integer count = redisService.get(AccessKey.access, user.getId() + "_" + url, Integer.class);
//        if(count == null) {
//            redisService.set(AccessKey.access, user.getId() + "_" + url, 1);
//        }else if(count < 5) {
//            redisService.incr(AccessKey.access, user.getId() + "_" + url);
//        }else{
//            return Result.error(CodeMsg.ACCESS_LIMIT_REACHED);
//        }

        // 检查verifyCode
        boolean check = miaoshaService.checkVerifyCode(user, goodsId, verifyCode);
        if(!check) {
            return Result.error(CodeMsg.REQUEST_ILLEGAL);
        }

        String str = MD5Util.md5(UUIDUtil.uuid() + "123456");
        redisService.set(MiaoshaKey.getMiaoshaPath, user.getId() + "_" + goodsId, str );
        return Result.success(str);
    }

    @RequestMapping(value = "/verifyCode", method = RequestMethod.GET)
    @ResponseBody
    public Result<String> getMiaoshaVerifyCode(HttpServletResponse response, MiaoshaUser user, @RequestParam("goodsId") long goodsId) {
        if (user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        try{
            BufferedImage image = miaoshaService.createVerifyCode(user, goodsId);
            OutputStream out = response.getOutputStream();
            ImageIO.write(image, "JPEG", out);
            out.flush();
            out.close();
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            return Result.error(CodeMsg.MIAO_SHA_FAIL);
        }

    }

    /**
     * 初始化方法，spring容器初始化完成后，会回调该方法
     * 初始化将商品库存加载到redis中
     * @throws Exception
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        List<GoodsVO> goodsVOList = goodsService.listGoodsVO();
        if(goodsVOList == null) {
            return;
        }
        for(GoodsVO goodsVO : goodsVOList) {
            redisService.set(GoodsKey.getMiaoshaGoodsStock, "" + goodsVO.getId(), goodsVO.getGoodsStock());
            localOverMap.put(goodsVO.getId(), false);
        }
    }
}
